package cn.lnexin.server;

import cn.lnexin.handler.IPProxyHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * 
 * @Description:TODO
 * @author Daniel
 * @date 2018年1月17日 下午4:38:30
 */
public class NettyServer {
	private int port;
	
	public NettyServer(int port) {
		this.port = port;
	}
	
	public void start() {
		ServerBootstrap b = new ServerBootstrap();
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workGroup = new NioEventLoopGroup();
		try {
			b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class);
			b.handler(new LoggingHandler(LogLevel.INFO));
			b.childHandler(new HandlerManager());
			b.option(ChannelOption.SO_BACKLOG, 256);
			b.childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);
			
			// 绑定端口,同步等待成功
			Channel channel = b.bind(port).sync().channel();
			System.out.println("HTTP SERVER PORT IS READY :" + port);
			// 等待服务器监听端口关闭
			channel.closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workGroup.shutdownGracefully();
		}
	}
	
	private class HandlerManager extends ChannelInitializer<SocketChannel> {
		/**
		 * 
		 * 为什么能有FullHttpRequest这个东西,就是因为有他,HttpObjectAggregator,如果没有他,就不会有那个消息是FullHttpRequest的那段Channel,同样也不会有FullHttpResponse
		 * 如果我们将HttpObjectAggregator(1024 * 1024)的参数含义是消息合并的数据大小，如此代表聚合的消息内容长度不超过1024kb
		 */
		@Override
		protected void initChannel(SocketChannel ch) throws Exception {
			ch.pipeline().addLast("decoder", new HttpRequestDecoder())				// 用于http request 解码
			        .addLast("aggregator", new HttpObjectAggregator(1024 * 1024))	// 限制一个请求只使用一个channel来处理
			        .addLast("encoder", new HttpResponseEncoder());					// 用于http response 编码
			ch.pipeline().addLast("/ip/*", new IPProxyHandler());		// 自定义handler
//			ch.pipeline().addLast("/api/test/*", new ReceiveActiveHandler());		// 自定义handler
		}
		
	}
}
